﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management.Automation;
using System.Net;
using System.Xml;
using System.IO;
using System.Web;

namespace Readify.Management.Automation.GoGrid
{
    [Cmdlet("Add", "GoGridLoadBalancer")]
    public class AddGoGridLoadBalancerCmdlet : Cmdlet
    {
        [Parameter(Mandatory = true)]
        public PSCredential Credential { get; set; }

        [Parameter(Mandatory = true)]
        public string Name { get; set; }

        [Parameter(Mandatory = true)]
        public string VirtualInterface { get; set; }

        [Parameter(Mandatory = true)]
        public string[] RealInterfaces { get; set; }

        [Parameter()]
        public string Description { get; set; }

        [Parameter()]
        public string Type { get; set; }

        [Parameter()]
        public string Persistence { get; set; }

        protected override void ProcessRecord()
        {
            string url = this.BuildUrl();

            XmlDocument document = GoGridHelper.ProcessRequest(url, this);
            XmlNodeList objectElementNodeList = document.SelectNodes("/gogrid/response/list/object[@name = 'loadbalancer']");

            foreach (XmlNode objectElementNode in objectElementNodeList)
            {
                GoGridLoadBalancer balancer = GoGridLoadBalancer.CreateFromXmlNode(objectElementNode);
                this.WriteObject(balancer);
            }
        }

        private string BuildUrl()
        {
            string url = this.BuildBasicUrl();
            url = this.AppendNameModifier(url);
            url = this.AppendVirtualInterfaceModifier(url);
            url = this.AppendRealInterfacesModifier(url);
            url = this.AppendTypeModifierIfNecessary(url);
            url = this.AppendPersistenceModifierIfNecessary(url);
            url = this.AppendDescriptionModifierIfNecessary(url);
            return url;
        }

        private string AppendRealInterfacesModifier(string url)
        {
            for (int realInterfaceIndex = 0; realInterfaceIndex < this.RealInterfaces.Length; realInterfaceIndex++)
            {
                string realInterfaceAsString = this.RealInterfaces[realInterfaceIndex];
                GoGridLoadBalancerInterface realInterface = GoGridLoadBalancerInterface.Parse(realInterfaceAsString);
                url = string.Format(
                    "{0}&realiplist.{1}.ip={2}&realiplist.{1}.port={3}",
                    url,
                    realInterfaceIndex,
                    realInterface.IPAddress.IPAddress,
                    realInterface.Port
                    );
            }

            return url;
        }

        private string AppendVirtualInterfaceModifier(string url)
        {
            GoGridLoadBalancerInterface virtualInterface = GoGridLoadBalancerInterface.Parse(this.VirtualInterface);
            url = string.Format(
                "{0}&virtualip.ip={1}&virtualip.port={2}",
                url,
                virtualInterface.IPAddress.IPAddress,
                virtualInterface.Port
                );
            return url;
        }

        private string AppendDescriptionModifierIfNecessary(string url)
        {
            if (!string.IsNullOrEmpty(this.Description))
            {
                string escapedDescription = HttpUtility.UrlEncode(this.Description);
                url = string.Format("{0}&description={1}", url, escapedDescription);
            }

            return url;
        }


        private string AppendNameModifier(string url)
        {
            string escapedName = HttpUtility.UrlEncode(this.Name);
            url = string.Format("{0}&name={1}", url, escapedName);
            return url;
        }

        private string AppendTypeModifierIfNecessary(string url)
        {
            if (!string.IsNullOrEmpty(this.Type))
            {
                return url;
            }

            string escapedType = HttpUtility.UrlEncode(this.Type);
            url = string.Format("{0}&type={1}", url, escapedType);
            return url;
        }

        private string AppendPersistenceModifierIfNecessary(string url)
        {
            if (!string.IsNullOrEmpty(this.Persistence))
            {
                return url;
            }

            string escapedPersistence = HttpUtility.UrlEncode(this.Persistence);
            url = string.Format("{0}&persistence={1}", url, escapedPersistence);
            return url;
        }

        private string BuildBasicUrl()
        {
            string urlFormat = "https://api.gogrid.com/api/grid/loadbalancer/add?api_key={0}&sig={1}&v=1.0&format=xml";

            NetworkCredential credential = this.Credential.GetNetworkCredential();
            string apiKey = credential.UserName;
            string secret = credential.Password;

            string signature = GoGridHelper.GenerateRequestSignature(apiKey, secret);

            string basicUrl = string.Format(urlFormat, apiKey, signature);
            return basicUrl;
        }
    }
}
